const ctxUser = ctx => ctx.request.user

const isLoggedIn = ctx => {
  const user = ctxUser(ctx)
  if (!user) throw new Error(`Not logged in`)
  return user
}

const isRequestingUserAlsoOwner = ({ ctx, userId, resource, typeId }) =>
  ctx.db.exists[resource]({ id: typeId, user: { id: userId } })
const isRequestingUser = ({ ctx, userId }) => ctx.db.exists.User({ id: userId })

const directiveResolvers = {
  isAuthenticated: (next, source, args, ctx) => {
    isLoggedIn(ctx)
    return next()
  },
  hasPremission: (next, source, { resource }, ctx) => {
    const { id } = isLoggedIn(ctx)
    // 判断 role 是否包含相关 resource 的使用权限
    // 根据 ctx 的 method 和 resource 能确定具体 premission 的 Action 和 Resource
    // 通过 userId, Action 和 Resource 查找 userId 是否符合条件
    /* if (roles.includes(role)) {
      return next()
    } */
    throw new Error(`Unauthorized, incorrect premission`)
  },
  isOwner: async (next, source, { resource }, ctx) => {
    const { id: typeId } =
      source && source.id
        ? source
        : ctx.request.body.variables
        ? ctx.request.body.variables
        : { id: null }
    const { id: userId } = isLoggedIn(ctx)
    const isOwner =
      resource === `User`
        ? userId === typeId
        : await isRequestingUserAlsoOwner({ ctx, userId, resource, typeId })
    if (isOwner) {
      return next()
    }
    throw new Error(`Unauthorized, must be owner`)
  },
  isOwnerOrHasPremission: async (
    next,
    source,
    { roles, resource },
    ctx,
    ...p
  ) => {
    const { id: userId, role } = isLoggedIn(ctx)
    if (roles.includes(role)) {
      return next()
    }

    const { id: typeId } = ctx.request.body.variables
    const isOwner = await isRequestingUserAlsoOwner({
      ctx,
      userId,
      resource,
      typeId
    })

    if (isOwner) {
      return next()
    }
    throw new Error(`Unauthorized, not owner or incorrect role`)
  }
}

module.exports = { directiveResolvers }
